package com.tavio.vaultboy.controller;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.camera.hud.HUD;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import android.view.MotionEvent;

import com.tavio.vaultboy.element.Element;

public abstract class Controller extends HUD implements IOnSceneTouchListener {
	private static final int INVALID_POINTER_ID = -1;
	protected final Sprite controlSprite;
	public float controlValue;
	private int mActivePointerID = INVALID_POINTER_ID;
	protected Element controlledElement;
	
	public Controller(int pX, int pY, Camera pCamera, ITextureRegion pControlBaseTextureRegion, VertexBufferObjectManager pVertexBufferObjectManager, Element controlledElement) {
		this.setCamera(pCamera);
		this.controlledElement = controlledElement;
		this.controlSprite = new Sprite(pX, pY, pControlBaseTextureRegion, pVertexBufferObjectManager) {
			@Override
			public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
				return Controller.this.onHandleControlSpriteTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY);
			}
		};

		this.setOnSceneTouchListener(this);
		this.registerTouchArea(this.controlSprite);
		this.attachChild(this.controlSprite);
		this.setTouchAreaBindingOnActionDownEnabled(true);
	}
	
	public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
		final int pointerID = pSceneTouchEvent.getPointerID();
		if(pointerID == this.mActivePointerID) {
			this.onHandleControlSpriteLeft();

			switch(pSceneTouchEvent.getAction()) {
				case MotionEvent.ACTION_UP:
				case MotionEvent.ACTION_CANCEL:
					this.mActivePointerID = INVALID_POINTER_ID;
			}
		}
		return false;
	}
	

	protected void onHandleControlSpriteLeft() {
		this.controlValue = 0;
	}
	
	protected void onHandleControlSpriteReleased() {
		this.controlValue = 0;
	}
	
	protected abstract void updateControlValue(final float pTouchAreaLocalX, final float pTouchAreaLocalY);
	
	protected boolean onHandleControlSpriteTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
		final int pointerID = pSceneTouchEvent.getPointerID();

		switch(pSceneTouchEvent.getAction()) {
			case MotionEvent.ACTION_DOWN:
				if(this.mActivePointerID == INVALID_POINTER_ID) {
					this.mActivePointerID = pointerID;
					this.updateControlValue(pTouchAreaLocalX, pTouchAreaLocalY);
					return true;
				}
				break;
			case MotionEvent.ACTION_UP:
			case MotionEvent.ACTION_CANCEL:
				if(this.mActivePointerID == pointerID) {
					this.mActivePointerID = INVALID_POINTER_ID;
					this.onHandleControlSpriteReleased();
					return true;
				}
				break;
			default:
				if(this.mActivePointerID == pointerID) {
					this.updateControlValue(pTouchAreaLocalX, pTouchAreaLocalY);
					return true;
				}
				break;
		}
		return true;
	}
}
